APPEND key value

2.0.0版本以上

时间复杂度:O(1)。平摊时间复杂度为O(1),假设附加的值很小,并且已经存在的现值是任意大小的,由于Redis使用的动态字符串库将使每次重新分配时可用的空闲空间增加一倍。

如果键已经存在并且是一个字符串,这个命令将在字符串的末尾追加值,如果键不存在,它将被创建并设置为空字符串,因此APPEND将类似于在这个特殊情况下SET

返回值

响应为整数:附加操作之后的字符串长度

例如

redis> EXISTS mykey
(integer) 0
redis> APPEND mykey "Hello"
(integer) 5
redis> APPEND mykey " World"
(integer) 11
redis> GET mykey
"Hello World"
redis> 

模式:时间序列

APPEND命令可用于创建一个非常紧凑的固定大小样本列表的表示形式,通常称为时间序列。每次新的样本到达时,我们都可以使用该命令存储它:

APPEND timeseries "fixed-size sample"

在时间序列中访问单个元素并不困难:

  • 可以使用STRLEN来获取样本的数量
  • GETRANGE允许对元素进行随机访问,如果我们的时间序列有相关的时间信息,我们可以很容易地实现一个二进制搜索,以获得GETRANGE与Redis 2.6中可用的Lua脚本引擎相结合的范围
  • SETRANGE可以用于覆盖现有的时间序列

这种模式的局限性是,我们被迫进入仅附加的操作模式,由于Redis目前缺少一个能够修饰字符串对象的命令,所以无法轻易地将时间序列缩减到给定的大小。然而,以这种方式存储的时间序列的空间效率是显著的。

提示:可以根据当前Unix时间切换到另一个键,通过这种方式,每个键可能只有相对少量的样本,为了避免处理非常大的键,并使这个模式更友好地分布在许多Redis实例中。

使用固定大小的字符串温度传感器的示例(在实际实现中使用二进制格式更好)

redis> APPEND ts "0043"
(integer) 4
redis> APPEND ts "0035"
(integer) 8
redis> GETRANGE ts 0 3
"0043"
redis> GETRANGE ts 4 7
"0035"
redis> 

BITCOUNT key [start end]

2.6.0版本以上
时间复杂度:O(N)

计算字符串中设置的bits数(总体计数)。

默认情况下,将检查字符串中包含的所有字节,可以只在通过附加参数开始和结束的间隔中指定计数操作。

GETRANGE命令一样,开始和结束可以包含负值,以便从字符串的末尾开始索引字节,-1是最后一个字节,-2是倒数第二个字节,以此类推。

不存在的键被视为空字符串,因此命令将返回0。

返回值

响应为整数:bits数被设置为1。

例如

redis> SET mykey "foobar"
"OK"
redis> BITCOUNT mykey
(integer) 26
redis> BITCOUNT mykey 0 0
(integer) 4
redis> BITCOUNT mykey 1 1
(integer) 6
redis>

模式:使用位图的实时度量

位图是对某些信息的一种非常节省空间的表示,例如需要用户访问历史记录的Web应用程序,这可以确定哪些用户是beta特性的良好目标。

使用SETBIT命令完成这个任务非常简单,每天都用一个小的递增整数进行标识,例如第0天是应用程序上线的第一天,第1天是第二天,以此类推。

每次用户执行页面视图时,应用程序都可以使用SETBIT命令设置与当前日期对应的位,在用户访问web站点的当天注册该页面。

稍后,只需根据位图调用BITCOUNT命令,就可以知道用户访问web站点的天数,这是很简单的。

使用用户id而不是天数的类似模式在文章中被描述为“使用Redis位图的快速简单实时度量

性能考虑

在上面的计数日示例中,即使10年之后,我们的应用程序仍然是在线的,每个用户只有365*10字节的数据,每个用户只有456字节,有了这些数据BITCOUNT,仍然和其他O(1) Redis命令(如GETINCR)一样快。

当位图较大时,有两种选择:

  • 取一个单独的键,每次修改位图时递增,使用一个小的Redis Lua脚本可以非常高效且具有原子性。
  • 使用BITCOUNT start和end可选参数递增地运行位图,在客户端积累结果,并可选地将结果缓存到一个键中。

博弈
2.5k 声望1.5k 粉丝

态度决定一切